
# 字符串中非重复字符的个数，不使用封装好的方法
print("caculate_longest_substring_length")
def caculate_longest_substring_length(str):
    num=len(str)
    left =0
    max_length=0
    char_index={}
    for right in range(0,num):
        if str[right] in char_index:
            left=char_index[str[right]]+1
        char_index[str[right]]=right
        max_length=max(max_length,right-left+1)
    return max_length
print(caculate_longest_substring_length("abcabcbb"))
print(caculate_longest_substring_length("abcabcdbb"))
print(caculate_longest_substring_length("aa"))
print(caculate_longest_substring_length("abc"))


# 题目1：字符串处理题目描述：
# 编写一个函数is_balanced_parentheses，该函数接收一个字符串作为参数，并判断该字符串中的括号是否平衡。
# 括号包括圆括号 ()、方括号 [] 和花括号 {
print("is_balanced_parentheses")
def is_balanced_parentheses(s:str)->bool:
    # 实现一
    # for i in range(len(s)//2):
    #     s=s.replace("()","").replace("[]","").replace("{}","")
    # return len(s)==0

    # 实现二
    stack=[]
    mapping={")":"(","]":"[","}":"{"}
    for ss in s:
        if ss in mapping:
            if len(stack)==0:
                return False
            if mapping.get(ss)!=stack.pop():
                return False
        else:
            stack.append(ss)
    return len(stack)==0

print(is_balanced_parentheses("()[]{}"))
print(is_balanced_parentheses("([)]"))

# 题目2：列表操作题目描述：
# 编写一个函数remove_duplicates_preserve_order，该函数接收一个列表作为参数，并返回一个新的列表，
# 其中去除了所有重复的元素，同时保持原有的顺序。
print("remove_duplicates_preserve_order")
def remove_duplicates_preserve_order(lst:list)->list:
    # 实现一
    # res=[]
    # for l in lst:
    #     if l not in res:
    #         res.append(l)
    # return res

    # 实现二：
    import collections
    counter=collections.Counter(lst)
    res=[]
    for key,value in counter.items():
        res.append(key)
    return res
print(remove_duplicates_preserve_order([1, 2, 2, 3, 4, 4, 5]))

# 题目3：字典操作题目描述：
# 编写一个函数get_max_value_key，该函数接收一个字典作为参数，并返回字典中值最大的键。
# 如果有多个键具有相同的最大值，则返回最先出现的那个键。
print("get_max_value_key")
def get_max_value_key(d:dict):
    # from operator import itemgetter
    # sorted_d=dict(sorted(d.items(),key=itemgetter(1),reverse=True))
    # print(sorted_d)
    # return list(sorted_d.keys())[0]

    sorted_d=dict(sorted(d.items(),key=lambda item:item[1],reverse=True))
    print(sorted_d)
    return list(sorted_d.keys())[0]

print(get_max_value_key({"a": 1, "b": 2, "c": 3}))

# 题目4：数据结构应用题目描述：
# 编写一个函数find_unique_number，该函数接收一个整数列表作为参数，并返回列表中唯一的一个不重复的数。
# 假设列表中只有一个数是不重复的
print("find_unique_number")
def find_unique_number(lst:list):
    # for l in lst:
    #     if lst.count(l)==1:
    #         return l

    import collections
    char_counter=dict(collections.Counter(lst))
    sorted_char_counter=sorted(char_counter.items(),key=lambda item:item[1])
    for k,v in sorted_char_counter:
        return k
print(find_unique_number([1, 1, 2, 2, 3]))

# 题目5：文件处理题目描述：
# 编写一个函数get_file_extension，该函数接收一个文件路径作为参数，并返回文件的扩展名。
# 如果文件没有扩展名，则返回空字符串。
print("get_file_extension")
def get_file_extension(file_path:str):
    path_list=file_path.split(".")
    if len(path_list)>1:
        return path_list[-1]
    return "123"
print(get_file_extension("/path/to/file.txt"))
print(get_file_extension("/path/to/file"))

# 题目6：字符串处理题目描述：
# 编写一个函数count_vowels，该函数接收一个字符串作为参数，并返回该字符串中元音字母的数量。
# 元音字母包括 a, e, i, o, u（忽略大小写）
print("count_vowels")
def count_vowels(s:str):
    yuanyin=["a", "e", "i", "o", "u"]
    res=0
    for ss in s:
        if ss.lower() in yuanyin:
            res+=1
    return res
print(count_vowels("Hello Worl"))

# 题目7：列表操作题目描述：
# 编写一个函数find_median，该函数接收一个整数列表作为参数，并返回列表中所有元素的中位数。
# 如果列表长度为偶数，则返回中间两个数的平均值。
print("find_median")
def find_median(lst:list):
    if len(lst)%2==0:
        return (lst[len(lst)//2]+lst[len(lst)//2-1])/2
    return lst[len(lst)//2]
print(find_median([1, 3, 5]))
print(find_median([1, 2, 3, 4]))

# 题目8：字典操作题目描述：
# 编写一个函数get_frequency_dict，该函数接收一个字符串作为参数，并返回一个字典，字典的键是字符串中的字符，
# 值是该字符出现的次数。
print("get_frequency_dict")
def get_frequency_dict(s:str):
    import collections
    return dict(collections.Counter(s))
print(get_frequency_dict("hello"))

# 题目9：数据结构应用题目描述：
# 编写一个函数is_subsequence，该函数接收两个字符串作为参数，并判断第一个字符串是否是第二个字符串的子序列。
# 子序列是指第一个字符串中的字符按照顺序出现在第二个字符串中，但不需要连续。
print("is_subsequence")
def is_subsequence(s,t):
    index=0
    for tt in t:
        if s[index]==tt:
            index+=1
        if index==len(s):
            return True
    return False
print(is_subsequence("abc", "ahbgdc"))
print(is_subsequence("axc", "ahbgdc"))

# 题目10：文件处理题目描述：
# 编写一个函数rename_files，该函数接收一个文件夹路径和一个前缀作为参数，
# 并将该文件夹中所有的文件重命名为前缀加上原始文件名。例如，文件file1.txt将被重命名为prefix_file1.txt。
print("rename_files")
import os
def rename_files(folder_path,prefix):
    if not os.path.isdir(folder_path):
        raise FileNotFoundError(f"the folder path {folder_path} does not exist")
    for filename in os.listdir(folder_path):
        # 获取文件完整路径
        full_file_path=os.path.join(folder_path+filename)
        print(full_file_path)
        # 检查是不是文件，而不是文件夹
        if os.path.isfile(full_file_path):
            # 生成新的的文件名
            new_filename=f"{prefix}_{filename}"
            new_full_file_path=os.path.join(folder_path,new_filename)
            os.rename(full_file_path,new_full_file_path)
            print(f"renamed: {filename} -> {new_filename}")
# rename_files(folder_path="./files2/",prefix="tzz")

# 题目11：字符串处理题目描述：
# 编写一个函数capitalize_words，该函数接收一个字符串作为参数，并返回一个新的字符串，其中每个单词的首字母都被大写。
print("capitalize_words")
def capitalize_words(s:str):
    # 只是将字符串的首字母转换为大写
    # print(s.capitalize())
    # 将以空格分隔的字符串的每个单词首字母大写  不一定非得是空格
    print(s.title())

capitalize_words("hello world")
capitalize_words("hello-world")
capitalize_words("hello_world")
capitalize_words("hello,world")

# 题目12：列表操作题目描述：
# 编写一个函数transpose_matrix，该函数接收一个二维列表（矩阵）作为参数，并返回该矩阵的转置。
# 即原矩阵的行变为新矩阵的列
print("transpose_matrix")
def transpose_matrix(matrix:list[list]):
    res=[]
    for i in range(0,len(matrix[0])):
        tem=[]
        # tem.append(matrix[0][i])
        # tem.append(matrix[1][i])
        for j in range(0,len(matrix)):
            tem.append(matrix[j][i])
        res.append(tem)
    return res
print(transpose_matrix([[1, 2, 3], [4, 5, 6]]))

# 题目13：字典操作题目描述：
# 编写一个函数combine_dicts，该函数接收多个字典作为参数，并返回一个新的字典，其中包含了所有输入字典的键值对。
# 如果存在重复的键，则最后一个字典中的值将被保留。
print("combine_dicts")
def hebingzidian(x:dict,y:dict):
    return {**x,**y}
def combine_dicts(*dicts):
    # res={**dicts[0],**dicts[1]}
    from functools import reduce
    res = reduce(hebingzidian,dicts)
    print(res)
combine_dicts({"a": 1, "b": 2}, {"b": 3, "c": 4},{"b": 6, "c": 7},{"d": 8, "e": 8})


# 题目14：数据结构应用题目描述：
# 编写一个函数find_first_non_repeating_char，该函数接收一个字符串作为参数，并返回字符串中第一个不重复的字符。
# 如果所有字符都重复，则返回None。
print("abca".count("a"))
print("find_first_non_repeating_char")
def find_first_non_repeating_char(s:str):
    # if not s or s=="":
    #     return None
    # for ss in s:
    #     if s.count(ss)==1:
    #         return ss
    # return None

    if not s or s=="":
        return None
    import collections
    counter=collections.Counter(s)
    # sorted_dict=dict(sorted(counter.items(),key=lambda item:item[1]))
    from operator import itemgetter
    sorted_dict=dict(sorted(counter.items(),key=itemgetter(1)))
    for k,v in sorted_dict.items():
        if v>1:
            return None
        return k
print(find_first_non_repeating_char("leetcode"))
print(find_first_non_repeating_char("loveleetcode"))

# 题目15：文件处理题目描述：
# 编写一个函数count_lines_in_files，该函数接收一个文件夹路径作为参数，并返回一个字典，其中的键是文件名，
# 值是对应的文件中的行数。
print("count_lines_in_files")
def count_lines_in_files(folder_path:str):
    import os
    if not os.path.isdir(folder_path):
        raise FileNotFoundError(f"the folder {folder_path} is not exist")
    file_count={}
    for file_name in os.listdir(folder_path):
        full_file_path=os.path.join(folder_path,file_name)
        if os.path.isfile(full_file_path):
            with open(full_file_path,mode="r",encoding="utf-8") as file:
                line_count=sum(1 for line in file)
            file_count[file_name]=line_count
    return file_count
print(count_lines_in_files("./files03/"))

# 题目16：字符串处理题目描述：
# 编写一个函数reverse_sentence，该函数接收一个句子作为参数，并返回一个新的字符串，
# 其中句子中的单词顺序被反转，但单词内部的字符顺序不变。
print("reverse_sentence")
def reverse_sentence(sentence:str):
    tem_list=sentence.split(" ")
    return " ".join(tem_list[::-1])
print(reverse_sentence("I love Python programming"))

# 题目17：列表操作题目描述：
# 编写一个函数reverse_odd_indices，该函数接收一个列表作为参数，并返回一个新的列表，其中奇数索引上的元素被反转，
# 偶数索引上的元素保持不变。
print("reverse_odd_indices")
def reverse_odd_indices(lst):
    if not lst or len(lst)<=1:
        return lst
    # for i in range(0,len(lst)//2):
    #     if i %2==1:
    #         lst[i],lst[len(lst)-1-i]=lst[len(lst)-1-i],lst[i]
    for index,value in enumerate(lst[:len(lst)//2]):
        if index %2==1:
            lst[index], lst[len(lst) - 1 - index] = lst[len(lst) - 1 - index], lst[index]
    return lst
print(reverse_odd_indices([1, 2, 3, 4, 5]))

# 题目18：字典操作题目描述：
# 编写一个函数filter_dict_by_value，该函数接收一个字典和一个阈值作为参数，并返回一个新的字典，
# 其中只包含那些值大于等于给定阈值的键值对。
print("filter_dict_by_value")
def filter_dict_by_value(d,threshold):
    res={}
    for k,v in d.items():
        if v>=threshold:
         res.setdefault(k,v)
    return res
print(filter_dict_by_value({"a": 1, "b": 2, "c": 3}, threshold=2))
# 题目19：数据结构应用题目描述：
# 编写一个函数find_missing_numbers，该函数接收一个整数列表作为参数，并返回一个新的列表，
# 包含从1到列表中最大数之间的所有缺失的整数
print("find_missing_numbers")
def find_missing_numbers(lst:list):
    res=[]
    lst.sort()
    for i in range(1,lst[-1]):
        if i not in lst:
            res.append(i)
    return res
print(find_missing_numbers([2, 3, 7, 4]))

# 题目20：文件处理题目描述：
# 编写一个函数move_files，该函数接收一个文件夹路径和一个目标文件夹路径作为参数，
# 并将源文件夹中的所有文件移动到目标文件夹中
print("move_files")
def move_files(source_folder,target_folder):
    import os
    if not os.path.exists(source_folder):
        print(f"source folder {source_folder} does not exists")
        return
    if not os.path.exists(target_folder):
        os.makedirs(target_folder)
    source_files=[f for f in os.listdir(source_folder)
                       if os.path.isfile(os.path.join(source_folder,f))]
    for file in source_files:
        source_file_path=os.path.join(source_folder,file)
        target_file_path=os.path.join(target_folder,file)
        import shutil
        shutil.move(source_file_path,target_file_path)
    print(f"all files from {source_folder} have been moved to {target_folder}")
# move_files("./files04_01/","./files04_02/")
move_files("./files04_02/","./files04_01/")




